home *** CD-ROM | disk | FTP | other *** search
/ Graphics Plus / Graphics Plus.iso / general / visulztn / saoimage / saoimage.lha / pancopy.c < prev    next >
C/C++ Source or Header  |  1990-04-20  |  8KB  |  245 lines

  1. #ifndef lint
  2. static char SccsId[] = "%W%  %G%";
  3. #endif
  4.  
  5. /* Module:    pancopy.c (Pan Copy)
  6.  * Purpose:    Copy data between short integer image buffers in different
  7.  *        flavors of blocking (used to fill pan buffer)
  8.  * Subroutine:    copy_buf_subsample()            returns: void
  9.  * Subroutine:    copy_buf_replicate()            returns: void
  10.  * Subroutine:    copy_buf_sum()                returns: void
  11.  * Subroutine:    copy_buf_max()                returns: void
  12.  * Copyright:    1988 Smithsonian Astrophysical Observatory
  13.  *        You may do anything you like with this file except remove
  14.  *        this copyright.  The Smithsonian Astrophysical Observatory
  15.  *        makes no representations about the suitability of this
  16.  *        software for any purpose.  It is provided "as is" without
  17.  *        express or implied warranty.
  18.  * Modified:    {0} Michael VanHilst    initial version          3 December 1988
  19.  *        {n} <who> -- <does what> -- <when>
  20.  */
  21.  
  22. #include <stdio.h>            /* define stderr, NULL, etc. */
  23. #include "hfiles/define.h"        /* define MIN, MAX, etc. */
  24.  
  25. /*
  26.  * Subroutine:    copy_buf_replicate
  27.  * Purpose:    Copy data from main buffer to pan buffer, zooming UP by
  28.  *        replicating. (for zoom > 1)
  29.  * Exception:    Assumes a perfect fit (edge to edge, all pixels mapped)
  30.  */
  31. void copy_buf_replicate ( ibuf, obuf, dupe, iwidth, owidth, oheight )
  32.      short *ibuf;        /* pointer to input buffer */
  33.      register short *obuf;    /* pointer in output buffer */
  34.      register int dupe;        /* imbuf to panbuf duplicating count */
  35.      int iwidth;        /* width of input buffer */
  36.      int owidth, oheight;    /* dimensions of output buffer */
  37. {
  38.   register short *ptr;        /* loop pointer in either buffer */
  39.   register short *rowend;    /* loop pointer to end of a row */
  40.   short *obufend;        /* pointer at end of output buffer */
  41.   short *thisband;        /* pointer to line to replicate for band */
  42.   short *nextband;        /* pointer to end of replicated band */
  43.   int bandsz;            /* pixels between bands */
  44.  
  45. #ifdef DEBUG
  46.   if( dupe <= 0 ) {
  47.     (void)fprintf(stderr, "pan zoom error\n");
  48.     return;
  49.   }
  50. #endif
  51.   obufend = obuf + (owidth * oheight);
  52.   bandsz = dupe * owidth;
  53.   /* quit when obuf is full */
  54.   while( obuf < obufend ) {
  55.     /* mark end of row replication */
  56.     thisband = obuf;
  57.     nextband = obuf + bandsz;
  58.     /* first make one row with column replication */
  59.     ptr = ibuf;
  60.     rowend = ibuf + iwidth;
  61.     do {
  62.       register int rep;
  63.       rep = 0;
  64.       while( rep++ < dupe )
  65.     *obuf++ = *ptr;
  66.     } while( ++ptr < rowend );
  67.     /* replicate this row as needed */
  68.     rowend = obuf;
  69.     while( obuf < nextband ) {
  70.       ptr = thisband;      
  71.       while( ptr < rowend )
  72.     *obuf++ = *ptr++;
  73.     }
  74.     ibuf += iwidth;
  75.   }
  76. }
  77.  
  78. /*
  79.  * Subroutine:    copy_buf_subsample
  80.  * Purpose:    Copy data between buffers, zooming down by sub-sampling
  81.  * Exception:    Assumes a perfect fit
  82.  */
  83. void copy_buf_subsample ( ibuf, obuf, subsample, iwidth, owidth, oheight )
  84.      short *ibuf;        /* pointer to input buffer */
  85.      register short *obuf;    /* pointer in output buffer */
  86.      register int subsample;    /* in to out sub-sampling increment */
  87.      int iwidth;        /* width of input buffer */
  88.      int owidth, oheight;    /* dimensions of output buffer */
  89. {
  90.   register short *iptr;        /* pointer within ibuf */
  91.   register int iptr_advance;    /* to advance iptr to start next row */
  92.   register short *rowend;    /* loop reference pointer to end of obuf row */
  93.   register short *obufend;    /* loop reference pointer to end of obuf */
  94.   int bufoff;             /* subsample offset into sample block */
  95.  
  96. #ifdef DEBUG
  97.   if( subsample <= 0 ) {
  98.     (void)fprintf(stderr, "pan zoom error\n");
  99.     return;
  100.   }
  101. #endif
  102.   /* initialize parameter values */
  103.   /* choose offsets to center the sample in block (not just start at 0) */
  104.   bufoff = MAX (0, ((subsample - 1) / 2));
  105.   /* center area of data by splitting remainder */
  106.   iptr = ibuf + ((bufoff * iwidth) + bufoff);
  107.   /* advance zoom lines minus what was ticked off (i*z - o*z) */
  108.   iptr_advance = (iwidth - owidth) * subsample;
  109.   /* quit when obuf is full */
  110.   obufend = obuf + (owidth * oheight);
  111.   /* loop through sub-sampling */
  112.   while( obuf < obufend ) {
  113.     /* MAKE A SUB-SAMPLED LINE */
  114.     rowend = obuf + owidth;
  115.     while( obuf < rowend ) {
  116.       *obuf++ = *iptr;
  117.       iptr += subsample;
  118.     }
  119.     iptr += iptr_advance;
  120.   }
  121. }
  122.  
  123. /*
  124.  * Subroutine:    copy_buf_sum
  125.  * Purpose:    Copy data between buffers, zoom down by summing or averaging
  126.  * Exception:    Assumes a perfect fit
  127.  */
  128. void copy_buf_sum ( ibuf, obuf, block, av, iwidth, owidth, oheight )
  129.      short *ibuf;        /* pointer to input buffer */
  130.      register short *obuf;    /* pointer in output buffer */
  131.      register int block;    /* blocking factor */
  132.      int av;            /* flag to select averaging */
  133.      int iwidth;        /* width of input buffer */
  134.      int owidth, oheight;    /* dimensions of output buffer */
  135. {
  136.   register short *iptr, *inextsum, *onextline;
  137.   short *isumline;
  138.   int blocksq, halfbsq;
  139.   int iadvance;
  140.   int oline;
  141.  
  142. #ifdef DEBUG
  143.   if( block <= 0 ) {
  144.     (void)fprintf(stderr, "pan zoom error\n");
  145.     return;
  146.   }
  147. #endif
  148.   if( av ) {
  149.     blocksq = block * block;
  150.     halfbsq = blocksq / 2;
  151.   }
  152.   iadvance = block * iwidth;
  153.   /* count the output lines */
  154.   for( oline=0; oline<oheight; oline++ ) {
  155.     bzero((char *)obuf, owidth);
  156.     isumline = ibuf + iadvance;
  157.     onextline = obuf + owidth;
  158.     /* make block passes with same out line, summing */
  159.     while( ibuf < isumline ) {
  160.       /* remember ibuf at start of this line */
  161.       iptr = ibuf;
  162.       /* go through output line block times */
  163.       while( obuf < onextline ) {
  164.     /* sum for block piece of line */
  165.     inextsum = iptr + block;
  166.     while( iptr < inextsum )
  167.       *obuf += *iptr++;
  168.     obuf++;
  169.       }
  170.       /* reset outline, advance inline */
  171.       obuf -= owidth;
  172.       ibuf += iwidth;
  173.     }
  174.     /* if averaging, divide by block squared (rounding) */
  175.     if( av ) {
  176.       /* make one more pass through outline, dividing */
  177.       /* put inc where compiler is sure to have it sequenced right */
  178.       do {
  179.     *obuf = (*obuf + halfbsq) / blocksq;
  180.       } while( ++obuf < onextline );
  181.     } else {
  182.       obuf = onextline;
  183.     }
  184.   }
  185. }
  186.  
  187. /*
  188.  * Subroutine:    copy_buf_max
  189.  * Purpose:    Copy data between buffers, zoom down by taking the max
  190.  * Exception:    Assumes a perfect fit
  191.  */
  192. void copy_buf_max ( ibuf, obuf, block, iwidth, owidth, oheight )
  193.      short *ibuf;        /* pointer to input buffer */
  194.      register short *obuf;    /* pointer in output buffer */
  195.      register int block;    /* blocking factor */
  196.      int iwidth;        /* width of input buffer */
  197.      int owidth, oheight;    /* dimensions of output buffer */
  198. {
  199.   register short *iptr, *inextsum, *onextline;
  200.   short *isumline;
  201.   int iadvance;
  202.   int oline;
  203.   short absmin;
  204.  
  205. #ifdef DEBUG
  206.   if( block <= 0 ) {
  207.     (void)fprintf(stderr, "pan zoom error\n");
  208.     return;
  209.   }
  210. #endif
  211.   absmin = -32767;
  212.   iadvance = block * iwidth;
  213.   /* count the output lines */
  214.   for( oline=0; oline<oheight; oline++ ) {
  215.     /* set line to lowest possible value (use isumline as temp storage) */
  216.     onextline = obuf + owidth;
  217.     isumline = obuf;
  218.     do {
  219.       *obuf = absmin;
  220.     } while( ++obuf < onextline );
  221.     obuf = isumline;
  222.     isumline = ibuf + iadvance;
  223.     /* make block passes with same out line, summing */
  224.     while( ibuf < isumline ) {
  225.       /* remember ibuf at start of this line */
  226.       iptr = ibuf;
  227.       /* go through output line block times */
  228.       while( obuf < onextline ) {
  229.     /* sum for block piece of line */
  230.     inextsum = iptr + block;
  231.     do {
  232.       if( *iptr > *obuf )
  233.         *obuf = *iptr;
  234.     } while( ++iptr < inextsum );
  235.     obuf++;
  236.       }
  237.       /* reset outline, advance inline */
  238.       obuf -= owidth;
  239.       ibuf += iwidth;
  240.     }
  241.     /* go on to next line */
  242.     obuf = onextline;
  243.   }
  244. }
  245.